﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using UnityEngine;

namespace DashFire
{
  class ResDownLoader
  {
    public static ResAsyncInfo StartDownload()
    {
      ResAsyncInfo info = new ResAsyncInfo();
      info.CurCoroutine = CoroutineProxy.Instance.StartCoroutine(StartDownloadAsync(info));
      return info;
    }
    public static ResAsyncInfo DownLoadResByName(string abName)
    {
      ResAsyncInfo info = new ResAsyncInfo();
      ResVersionData data = ResVersionProvider.Instance.GetDataByAssetBundleName(abName);
      info.CurCoroutine = CoroutineProxy.Instance.StartCoroutine(DownLoadResAsync(data, info));
      return info;
    }
    private static IEnumerator StartDownloadAsync(ResAsyncInfo info)
    {
      ResUpdateControler.s_SheetZipList.Clear();
      List<string> toUpgradeRes = new List<string>();
      ResUpdateTool.SearchUpgradeRes(toUpgradeRes);
      if (toUpgradeRes != null && toUpgradeRes.Count > 0) {
        string tipFormat = Dict.Get("StrDictionary_String_23");
        if (string.IsNullOrEmpty(tipFormat)) {
#if LOCAL_KR
          tipFormat = "현재 {0}K / {1}K";
#elif LOCAL_EF
          tipFormat = "已下载 {0}K / {1}K";
#else
          tipFormat = "已下载 {0}K / {1}K";
#endif
        }

        long accSize = 0;
        long totalSize = ResLoadHelper.CaculateABSize(toUpgradeRes);

        LogicForGfxThread.UpdateLoadingTip(string.Format("正在下载资源，共{0}K", ResUpdateTool.FormatNumber((float)totalSize / (1024))));
        yield return 1;

        foreach (string abName in toUpgradeRes) {
          ResVersionData data = ResVersionProvider.Instance.GetDataByAssetBundleName(abName);
          if (data == null) {
            continue;
          }
          ResAsyncInfo loadAssetInfo = DownLoadResByName(abName);
          loadAssetInfo.Target = (System.Object)(abName);
          while (true) {
            if (loadAssetInfo.IsError) {
              ResLoadHelper.Log("更新资源错误 ab:" + loadAssetInfo.Tip);
              info.IsError = true;
              ResUpdateControler.s_UpdateError = ResUpdateError.ResDownloader_Asset_Error;
              break;
            } else {
              long curSize = (long)(accSize + data.m_Size * loadAssetInfo.Progress);
              info.Progress = (float)(curSize / ((totalSize > 0) ? totalSize : double.Epsilon));
              info.Tip = string.Format(tipFormat,
                ResUpdateTool.FormatNumber((float)curSize / (1024)),
                ResUpdateTool.FormatNumber((float)totalSize / (1024)));
              LogicForGfxThread.UpdateLoadingProgress(info.Progress);
              LogicForGfxThread.UpdateLoadingTip(info.Tip);
              if (loadAssetInfo.IsDone) {
                accSize += data.m_Size;
                break;
              } else {
                yield return 1;
              }
            }
          }
          if (ResUpdateControler.s_DownLoadNum >= 20) {
            ResVersionLoader.SaveClientResVersion();
            ResUpdateControler.s_DownLoadNum = 0;
          }
        }
      }

      if (ResUpdateControler.s_SheetZipList.Count > 0) {
        ResUpdateControler.s_SheetZipList.Sort();
        foreach (string curSheetZipFile in ResUpdateControler.s_SheetZipList) {
          ResAsyncInfo extractResSheetInfo = ResSheetLoader.ExtractResSheet(curSheetZipFile, true);
          if (extractResSheetInfo.CurCoroutine != null) {
            yield return extractResSheetInfo.CurCoroutine;
          }
          if (extractResSheetInfo.IsError) {
            ResLoadHelper.Log("解压更新的表格资源列表错误");
            info.IsError = true;
            //yield break;
          }
          string curSheetZipPath = ResLoadHelper.GetFilePath(ResPathType.Cache, curSheetZipFile);
          if (File.Exists(curSheetZipPath)) {
            File.Delete(curSheetZipPath);
          }
        }
        ResUpdateControler.s_SheetZipList.Clear();
      }

      LogicForGfxThread.UpdateLoadingProgress(1.0f);
      info.IsDone = true;
      info.Progress = 1.0f;
    }
    private static IEnumerator DownLoadResAsync(ResVersionData data, ResAsyncInfo info)
    {
      if (Application.internetReachability == NetworkReachability.NotReachable) {
        ResLoadHelper.Log("DownLoadResAsync network not reachable:");
        info.IsError = true;
        ResUpdateControler.s_UpdateError = ResUpdateError.Network_Error;
        yield break;
      }

      string url = ResLoadHelper.GetFilePath(ResPathType.Remote, data.m_Version + "/" + data.m_AssetBundleName);
      info.Tip = data.m_AssetBundleName;
      url = ResLoadHelper.GetDynamicUrl(url);
      using (WWW tWWW = new WWW(url)) {
        //tWWW.threadPriority = ThreadPriority.High;
        while (true) {
          if (tWWW.isDone || tWWW.error != null) {
            break;
          } else {
            info.Progress = tWWW.progress;
            yield return 1;
          }
        }
        //yield return tWWW;
        try {
          if (tWWW.error != null || (tWWW.text != null && tWWW.text.ToLower().Contains("<html"))) {
            ResLoadHelper.Log("DownLoadRes error data:" + data.m_AssetBundleName + " Url:" + url);
            info.IsError = true;
            ResUpdateControler.s_UpdateError = ResUpdateError.ResDownloader_WWW_Error;
            tWWW.Dispose();
            yield break;
          }
          if (!ResUpdateTool.SaveCacheAB(tWWW.bytes, data, true)) {
            throw new Exception(string.Format("DownLoadRes save ab failed. url:{0} abName:{1}", url, data.m_AssetBundleName));
          }
          if (data.m_AssetName == ResUpdateConfig.s_ResSheetZipName) {
            ResUpdateControler.s_SheetZipList.Add(data.m_AssetBundleName);
          }
        } catch (System.Exception ex) {
          ResLoadHelper.Log("DownLoadRes ex:" + ex);
          info.IsError = true;
          ResUpdateControler.s_UpdateError = ResUpdateError.ResDownloader_Save_Error;
          yield break;
        } finally {
          tWWW.Dispose();
        }
      }

      info.IsDone = true;
      info.Progress = 1.0f;
    }
  }
}
